/*
 * usea, Copyright 2011 André König
 * Hochschule Bremen - University of Applied Sciences - All Rights Reserved.
 *
 * $Id: Cui.java 17 2011-07-06 06:51:01Z andre.koenig $
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * Contact:
 *     André König: akoenig@stud.hs-bremen.de
 * 
 * Web:
 *     http://tutorium-prog2.tumblr.com
 * 
 */
package de.hochschule.bremen.usea.client.ui;

import java.net.UnknownHostException;
import java.util.Vector;

import de.hochschule.bremen.usea.client.net.ClientMethodsImpl;
import de.hochschule.bremen.usea.client.utils.IO;
import de.hochschule.bremen.usea.commons.exceptions.LoginFailureException;
import de.hochschule.bremen.usea.commons.net.ServerMethods;
import de.hochschule.bremen.usea.commons.vo.Article;
import de.hochschule.bremen.usea.commons.vo.User;
import de.root1.simon.Lookup;
import de.root1.simon.Simon;
import de.root1.simon.exceptions.EstablishConnectionFailed;
import de.root1.simon.exceptions.LookupFailedException;
import de.root1.simon.exceptions.SimonRemoteException;

public class Cui {

	private static Thread uiThread = null;
	
	// Ueber dieses Objekt ist es möglich die Methoden auf dem Server ausfuehren zu koennen,
	// die in der Schnittstelle "ServerMethods" (s. Commons-Projekt) beschrieben wurden.
	private static Lookup connection = null;
	private static ServerMethods server = null;
	
	/**
	 * Starten der CUI.
	 *
	 */
	public void run() {
		
		try {

			//
			// 1. Schritt: Verbindung zum Server herstellen.
			//
			this.connect();

			//
			// 2. Schritt: Starten der Eingabeschleife
			//
			// Diese muss in einem eigenen Thread (nur bei einer CUI) realisiert werden, da
			// der Server sonst keine Möglichkeit hat die "Ping-Methode" auszuführen.
			// Eine Schleife, die auf die Eingabe des Benutzers "wartet", blockiert die Anwendung.
			//
			uiThread = new Thread(new Runnable() {
				
				@Override
				public void run() {
					
					// Ist der Benutzer eingeloggt, so wird diese Variable angepasst.
					// Kleiner Sicherheitsmechanismus, der regelt, dass der Benutzer
					// keine Artikel-Listen abrufen bzw. keine Artikel editieren kann.
					boolean authenticated = false;

					char input = ' ';

					do {
						switch (input) {

					        //
					        // 'l' - Login
					        //
					        // Login eines Benutzers.
					        //
					        //
						    case 'l':
						    	if (!authenticated) {
						    		System.out.println();
								    System.out.println("# Login");
								    System.out.println();
								    
								    System.out.println("> Bitte geben Sie Ihre E-Mail Adresse ein: ");
								    String email = IO.readString();
								
								    System.out.println("> Bitte geben Sie Ihr Passwort ein: ");
								    String password = IO.readString();
								   
								    // Erstellung des Benutzer-Objektes anhand der eingegebenen Daten.
								    // Dieses User-Objekt wird im Anschluss an den Server mittels des
								    // Login-Methodenaufrufes uebermittelt.
								    User user = new User(email, password);

								    try {
										server.login(user, new ClientMethodsImpl());

										System.out.println();
										System.out.println("> Login war erfolgreich ;)");
										System.out.println();

										authenticated = true;

									// Exception: Login war nicht erfolgreich ...
									} catch (LoginFailureException e) {
										Cui.printError(e.getMessage());
										
									// Exception: Fehler bei der Kommunikation
									} catch (SimonRemoteException e) {
										Cui.printError(e.getMessage());
									}
								    
						    	} else {
						    		System.out.println();
						    		System.out.println("> Sie sind bereits eingeloggt.");
						    		System.out.println();
						    	}
						    break;
						    
						    //
						    // 'a' - Artikel-Liste
						    //
						    // Abrufen aller Artikel vom Server und Ausgabe dieser auf der Konsole.
						    //
						    //
						    case 'a':
						    	if (authenticated) {
						    		System.out.println();
								    System.out.println("# Ausgabe der verfuegbaren Artikel");
								    System.out.println();
						    		Vector<Article> articles = server.getArticleList();
						    		
						    		for (Article article : articles) {
						    			System.out.println(article);
						    		}
						    	} else {
						    		Cui.printError("Bitte erst einloggen ...");
						    	}
						    break;
						    
						    //
						    // 'e' - Einen Artikel bearbeiten
						    //
						    // Abrufen aller Artikel vom Server und anschliessende Bearbeitung eines Artikels durch den Benutzer.
						    //
						    //
						    case 'e':
						    	if (authenticated) {
						    		System.out.println();
								    System.out.println("# Bearbeiten eines Artikels ...");
								    System.out.println();
						    		Vector<Article> articles = server.getArticleList();
						    		
						    		for (Article article : articles) {
						    			System.out.println(article);
						    		}
						    		
						    		System.out.println();
								    System.out.println("> Welchen Artikel möchten Sie bearbeiten? ...");
								    System.out.println();
								    System.out.println("> ID: ");
								    int id = IO.readInt();
								    
								    Article editable = null;

								    for (Article article : articles) {
								    	if (article.getId() == id) {
								    		editable = article;
								    	}
								    }
								    
								    if (editable != null) {
								    	System.out.println();
									    System.out.println("> Bitte geben Sie den neuen Namen ein (vorher: " + editable.getName() + "):");
									    System.out.println();
									    editable.setName(IO.readString());
									    
									    System.out.println();
									    System.out.println("> Bitte geben Sie den neuen Bestand ein (vorher: " + editable.getBestand()+ "):");
									    System.out.println();
									    editable.setBestand(IO.readInt());
									    
									    System.out.println();
									    System.out.println("> Bitte geben Sie den neuen Preis ein (vorher: " + editable.getPreis()+ "):");
									    System.out.println();
									    editable.setPreis(IO.readDouble());
									    
									    // Neuen bearbeiteten Artikel an den Server uebertragen.
									    server.save(editable);
								    } else {
								    	Cui.printError("Der gewuenschte Artikel wurde nicht gefunden ...");
								    }
						    		
						    	} else {
						    		Cui.printError("Bitte erst einloggen ...");
						    	}
						    break;
						}

						Cui.printMenue();
						
					} while ((input = IO.readChar()) != 'x');
					
					//
					// Wurde die Schleife verlassen, so moechte der Benutzer die Anwendung
					// beenden. Um die Anwendung "sauber" beenden zu können, muss noch die Verbindung
					// zum Server beendet werden.
					//
					connection.release(server);
				}
			});

			uiThread.start();
		} catch (UnknownHostException e) {
			Cui.printError(e.getMessage());
		} catch (LookupFailedException e) {
			Cui.printError(e.getMessage());
		} catch (EstablishConnectionFailed e) {
			Cui.printError(e.getMessage());
		}
	}
	
	/**
	 * Diese Methode stellt die Verbindung zu dem Server her.
	 *
	 * @throws LookupFailedException
	 * @throws EstablishConnectionFailed
	 * @throws UnknownHostException
	 *
	 */
	private void connect() throws LookupFailedException, EstablishConnectionFailed, UnknownHostException {
		Cui.connection = Simon.createNameLookup("localhost", 50001);
		Cui.server = (ServerMethods) Cui.connection.lookup("usea");  
	}

	//
	//
	// METHODEN DER CUI
	//
	// Menues, Eingabeoperationen, etc.
	//
	//

	private static void printMenue() {
		System.out.println("= A 'usea' client!!");
		System.out.println();
		System.out.println("= Hauptmenue:");
		System.out.println();
		System.out.println("= 'l' - Login ...");
		System.out.println("= 'a' - Alle verfuegbaren Artikel auflisten ...");
		System.out.println("= 'e' - Einen Artikel editieren ...");
		System.out.println();
		System.out.println("= 'x' - Diesen Client beenden ...");
		System.out.println();
		System.out.println("> Where do you want to go today? ;)");
		

	}
	
	/**
	 * Gibt die übergebene Fehlermeldung aus.
	 *
	 */
	private static void printError(String message) {
		System.out.println();
		System.err.println("[ERROR] " + message);
		System.out.println();
	}
}
